package com.bl.nio.common.entity;

import com.bl.nio.common.pack.EventPack;
import com.bl.nio.common.pack.HeartbeatPack;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.UUID;

import lombok.Data;

/**
 * @author 作者 : blownsow
 * @version 版本: 1.0
 * @date 创建时间 : 2019/12/7 10:51
 * @describe 类描述:
 */
@Data
public class SocketClient{
    private String clientId;
    private Socket socket;
    private int timeout;
    private Timer timer;
    private Object token;

    public EventPack sendEventPack(EventPack eventPack) throws IOException {
        send(eventPack);
        return eventPack;
    }

    public EventPack sendEventPack(String eventName,Object object) throws IOException {
        EventPack eventPack = new EventPack();
        eventPack.setName(eventName);
        eventPack.setData(object);
        eventPack.setUuid(UUID.randomUUID().toString());
        send(eventPack);
        return eventPack;
    }

    public Object read() throws IOException {
        InputStream inputStream = socket.getInputStream();
        int available = inputStream.available();
        byte[] bytes = new byte[available];
        inputStream.read(bytes);
        return deserialize(bytes);
    }

    public void send(Object o) throws IOException {
        byte[] serialize = serialize(o);
        socket.getOutputStream().write(serialize);
        socket.getOutputStream().flush();
//        send(o);
    }

    protected byte[] serialize(Object data) {
        byte[] dataArray = null;
        try {
            //1、创建OutputStream对象
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            //2、创建OutputStream的包装对象ObjectOutputStream，PS：对象将写到OutputStream流中
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
            //3、将对象写到OutputStream流中
            objectOutputStream.writeObject(data);
            //4、将OutputStream流转换成字节数组
            dataArray = outputStream.toByteArray();

            objectOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataArray;
    }

    protected Object deserialize(byte[] data) {
        Object object = null;

        try {
            ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
            ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
            object = objectInputStream.readObject();

            objectInputStream.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return object;
    }


    //发送心跳包
    public void sendHeartbeatPack() throws IOException {
        sendHeartbeatPack(1);
    }
    public void sendHeartbeatPack(int status) throws IOException {
        HeartbeatPack heartbeatPack = new HeartbeatPack();
        heartbeatPack.setStatus(status);
        send(heartbeatPack);
    }

    public void close(){
        if (timer != null){
            timer.cancel();
        }
        try {
            sendHeartbeatPack(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            socket.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
